package edu.map.aamas.logging;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import edu.map.aamas.gui.Tadpole;
import edu.map.aamas.rnn.RNN;
import edu.map.aamas.rnn.RnnListener;

public class RNNLogger implements RnnListener {

	public String logs_dir = "logs";
	
	public BufferedWriter writer = null;
	public String outFilename = null;
	private static SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");
	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_");
	private NumberFormat df;
	private boolean forcedFilename = false;
	
	private static String getTimeStamp() {
		return timeFormat.format(new Date(System.currentTimeMillis()));
	}
	
	private static String getDateStamp() {
		return dateFormat.format(new Date(System.currentTimeMillis()));
	}
	
	public void forceFilename(String dir, String filename) {
		if (writer != null) {
			try {
				writer.close();
				writer = null;
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		File f = new File(".", dir);
		f.mkdirs();
		f = new File(f, filename);
		outFilename = f.getAbsolutePath();
		
		try {
			writer = new BufferedWriter(new FileWriter(outFilename));
			writeHeader();
		}
		catch (Exception e) {
			e.printStackTrace();
			return;
		}
		forcedFilename = true;
		
		System.out.println("filename is now "+outFilename);
		
	}
	
	public void logState()  {

		if (writer == null) {
			outFilename = dateFormat.format(new Date())+timeFormat.format(new Date())+".txt";
			File dir = new File(".",logs_dir);
			dir.mkdir();
			try {
				writer = new BufferedWriter(new FileWriter(dir.getAbsolutePath()+"/"+outFilename));
				writeHeader();
			}
			catch (Exception e) {
				e.printStackTrace();
				return;
			}
		}
		
		writeState();
		
	}
	
	private void writeHeader() {
		
		try {
			writer.write("Iteration\tX\tY\tSpeed\tAngular Speed\tKinetic Energy\r\n");
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private void writeState() {
		if (df == null) {
			df = DecimalFormat.getInstance(Locale.getDefault());
			df.setGroupingUsed(false);
			df.setMaximumFractionDigits(3);			
		}
		try {
			writer.write(
				RNN.getInstance().iteration+"\t"+
				df.format(Tadpole.getInstance().getPosition().x)+"\t"+
				df.format(Tadpole.getInstance().getPosition().y)+"\t"+
				df.format(Tadpole.getInstance().instantSpeed)+"\t"+
				df.format(Tadpole.getInstance().angularSpeed)+"\t"+
				df.format(RNN.getInstance().kineticEnergy())+"\r\n"
			);
			writer.flush();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void rnnRestarted(RNN rnr) {
		if (forcedFilename)
			return;
		
		if (!rnr.loggingEnabled)
			return;
		
		if (writer != null) {
			try {
				writer.close();
				writer = null;
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
		logState();
	}

	public void rnnUpdated(RNN rnr) {
		if (rnr.loggingEnabled)					
			logState();
	}
}
